<!-- summary
目标：定位为基础图片。用作占位，实现快速开发，兼顾细节处理：加载动效、错误提示、图片预览、路由快捷跳转、默认底图等。 
-->
<template>
  <el-image
    class="base-img"
    :data-circle="circle"
    :data-pointer="!!to || !!$attrs.onClick"
    :data-disabled="disabled || !src"
    :data-empty="!src"
    :src="src || emptyImg"
    :data-size="!!(width || height)"
    @click="handleClick"
    v-bind="newAttrs"
  >
    <template #placeholder>
      <div class="err-box f-c-c-c">
        <el-icon class="rotate" :size="iconSize" name="Loading">
          <Loading />
        </el-icon>
        <span class="tips">{{ loadTips }}</span>
      </div>
    </template>
    <template #error>
      {{ $emit("error") }}
      <el-image class="base-img" :class="{ circle }" :src="errImgSrc" v-bind="defaultImageAttrs" v-if="errImgSrc" />
      <div class="err-box f-c-c-c" v-else>
        <el-icon :size="iconSize" name="Picture">
          <Picture />
        </el-icon>
        <span class="tips" v-if="errTips">{{ errTips }}</span>
      </div>
    </template>
  </el-image>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { useRouter } from "vue-router";
import { getCssNum, toCssVal } from "@/utils";
import { CommonObj, CommonSize, RouteTo, StrNum } from "@/_types";
import emptyImg from "@/assets/images/default/img.png";
import { Loading, Picture } from "@element-plus/icons-vue";
import { useAttrs } from "vue";

export type ImgFitType = "fill" | "contain" | "cover" | "none" | "scale-down";
// const sizeMap: CommonObj = {
//   large: 26,
//   default: 22,
//   small: 18,
// };
// 默认的图片属性
const defaultImageAttrs = {
  fit: "cover", // ImgFitType
  previewTeleported: true,
  hideOnClickModal: true,
};
const router = useRouter();
const props = withDefaults(
  defineProps<{
    size?: StrNum;
    iconSize?: number;
    width?: StrNum;
    height?: StrNum;
    to?: RouteTo;
    src?: string;
    circle?: boolean;
    stop?: boolean; // 点击图片时，是否阻止冒泡
    preview?: boolean;
    disabled?: boolean;
    loadTips?: string;
    errTips?: string;
    errImgSrc?: string;
    // 其他同 el-image 的属性
    // fit?: ImgFitType;
    // initialIndex?: number;
  }>(),
  {
    loadTips: "玩命加载中…",
    errTips: "加载失败",
    preview: true,
    width: (_props: CommonObj) => _props.size,
    height: (_props: CommonObj) => _props.size,
    iconSize: ({ width, height }) => Math.max(getCssNum(width), getCssNum(height)) * 0.1,
  }
);
const $emit = defineEmits(["error"]);
const $attrs = useAttrs();
const newAttrs = computed<CommonObj>(() => {
  const { to, src, preview } = props;
  if (to || $attrs.onClick || !src || !preview) return defaultImageAttrs;
  return { ...defaultImageAttrs, previewSrcList: [src] };
});

// 处理点击图片
function handleClick(e: any) {
  const { src, to, stop, disabled } = props;
  if (!src) return e.prevent();
  if (stop) e.stopImmediatePropagation();
  if (disabled) return;
  if (to) return router.push(to);
}
</script>

<style lang="scss" scoped>
.base-img {
  display: block; // 去除inline-block的间隙
  border-radius: $radius-main;
  &[data-size="true"] {
    width: v-bind(width);
    height: v-bind(height);
  }
  &[data-circle="true"] {
    border-radius: 50%;
  }
  &[data-pointer="true"] {
    cursor: pointer;
  }
  &[data-disabled="true"] {
    cursor: not-allowed;
  }
  &[data-empty="true"] {
    color: $color-text-light;
    font-size: 12px;
    background: $color-bg-lighter;
  }
  .err-box {
    height: 100%;
    width: 100%;
    color: $color-text-light;
    background: $color-bg-lighter;
    .tips {
      margin-top: $gap-qtr;
      font-size: 12px;
      line-height: 1;
    }
  }
}
</style>
